import { useState, useEffect } from 'react'
import { useBlCookie } from '@/stores/bilibili' // 导入状态
import {
  Avatar, Button, Col, Data, Dialog, Form, Input,
  MessagePlugin, Popup, Radio, Row, SelectInput,
  SubmitContext, Progress
} from 'tdesign-react'
import { SearchIcon } from 'tdesign-icons-react'
import QRCode from 'qrcode'
import styles from './index.module.less'
import { ApiRequest, apis } from '@/service'
import { useNavigate } from 'react-router-dom'
const { FormItem, useForm } = Form
const {
  search: {
    getSearchSuggest,
    getHotword
  },
  login: {
    getUserNavInfo,
    getUserNavStat,
    getQrCode,
    useQrCode,
    logout
  },
} = apis.BilibiliService
let timer: any = null
let qrTimer: any = null
let qrVerificationTimer: any = null

const Header = (props: any) => {

  const {
    onChange = () => { },
    className,
    keyword
  } = props

  const { blCookie, setBlCookie, resetBlCookie } = useBlCookie((state: any) => state)

  const [popupVisible, setPopupVisible] = useState<boolean>(false)
  const [searchValue, setSearchValue] = useState<string>('')
  const [options, setOptions] = useState<any>([])
  const [hotwordList, setHotwordList] = useState<any>([])
  const [searchSuggest, setSearchSuggest] = useState<any>('')
  const [loginDialogVisible, setLoginDialogVisible] = useState<boolean>(false)
  const [isRegister, setIsRegister] = useState<boolean>(false) //是否为注册页
  const [loginInfo, setLoginInfo] = useState<any>(JSON.parse(localStorage.getItem('loginInfo') || '{}')) //是否已登录
  const [QrCode, serQrCode] = useState<any>({})
  const [isQrCodeExpired, setIsQrCodeExpired] = useState<boolean>(false)
  const [formRef] = useForm()
  const navigate = useNavigate()

  useEffect(() => {
    getHotwordFnc('hotword')
    console.log('cookie', document.cookie)
    if (!loginInfo && document.cookie) {
      getUserNavStatFnc()
    }
    console.log('nav_key', localStorage.getItem('nav_keys'))
  }, [])

  useEffect(() => {
    console.log('blCookie', blCookie)
  }, [blCookie])

  useEffect(() => {
    useQrCodeFnc(QrCode.qrcode_key) // 这个函数是用来获取扫码状态的嗯，所以无需其他操作，刷新出二维码就会定时调用是的
  }, [QrCode])

  useEffect(() => {
    setSearchValue(keyword)
  }, [keyword])

  useEffect(() => {
    console.log('loginInfo', loginInfo)
    if (loginInfo && loginInfo.mid && !loginInfo.follower) {
      getUserNavStatFnc()
    }
  }, [loginInfo])

  const getQrCodeFnc = () => {
    ApiRequest({ api: getQrCode }).then((res: any) => {
      console.log('getQrCodeFnc', res) // 这里没做错误处理，最好是做一下，反正不赶时间
      const { code = -1, note = '', data = [] } = res
      if (code > 0) {
        QRCode.toDataURL(data[0].url, (error: any, url: string) => {
          if (error) {
            console.error(error);
          } else {
            serQrCode({ qrcode_key: data[0].qrcode_key, url })
            console.log("QR Code image successfully generated!");
            if (qrTimer) {
              clearTimeout(qrTimer)
              setIsQrCodeExpired(false)
            }
            qrTimer = setTimeout(() => { setIsQrCodeExpired(true) }, 180 * 1000);
          }
        })
      }
    })
  }
  const useQrCodeFnc = (key: string) => {
    if (!key || loginInfo.face) return
    const params = {
      qrcode_key: key
    }
    ApiRequest({ api: useQrCode, params }).then((res: any) => {
      const { code = -1, note = '', data = [] } = res

      if (qrVerificationTimer) {
        clearInterval(qrVerificationTimer)
      }
      qrVerificationTimer = setInterval(() => {
        useQrCodeFnc(key)
      }, 5000)
      if (code < 0) {
        clearInterval(qrVerificationTimer)
      }
      if (code == 1) {
        // 我们以这个 cookie 为例，我们想把cookie 存储起来，现在使用store方式
        let cookie = data[0].cookie //原本的cookie
        console.log('cookie', cookie)
        if (cookie) {
          setBlCookie(cookie)
          // document.cookie = decodeURIComponent(cookie) // 解析cookie
          // console.log(decodeURIComponent(cookie), 'cookie')
        }
        toLogin()
      }
      if (code > 1) {
        console.log('useQrCodeFnc', res)
      }
      // if (res.data.code === 1) { // 扫码登录成功
      //   console.log(res.data)
      //   let cookie = res.data?.data?.[0]?.cookie
      //   console.log(cookie)
      //   if (cookie) {
      //     document.cookie = decodeURIComponent(cookie) // 解析cookie
      //   }
      //   clearInterval(qrVerificationTimer)
      //   toLogin()
      // }
    })
  }
  const getUserNavInfoFnc = () => {
    ApiRequest({ api: getUserNavInfo }).then((res: any) => {
      console.log('getUserNavInfoFnc', res.data)
      setLoginInfo(res.data)
      localStorage.setItem('loginInfo', JSON.stringify(res.data))
    })
  }
  const getUserNavStatFnc = () => {
    ApiRequest({ api: getUserNavStat }).then((res: any) => {
      console.log('getUserNavStatFnc', res.data)
      setLoginInfo({...loginInfo, ...res.data})
    })
  }
  const onInputChange = (keyword: string) => {
    setSearchValue(keyword)
    debounce(() => { getSearchSuggestFnc(keyword) }, 500)
    // getSearchSuggestFnc(keyword)
  }
  // 最直接的提升是，接口调用次数变少了很多，每个字符输入的间隔大于500ms才会触发一次搜索
  // 如果是旧版本的话，每输入一个字符就会触发一次搜索嗯
  // 最直观的提升是，你输入完了之后，不会出现下面的建议信息一直在变的情况
  // 比如现在 它没做防抖，而且能够有效规避 被ip封禁的风险，行
  // 原理是，我们写了一个计时器，然后放在了这个组件的外面（为什么要放在外面）
  // 然后当我触发这个函数的时候，我就设置一个延时执行的函数，如果它在500ms里面没有再次触发
  // 那么就会按时执行这个函数，如果它在500ms里面再次触发，就清除掉之前的计时器，并且重新创建一个计时器，延迟依然是500ms嗯，也可以使用节流，防抖、节流本质的做法都是为了减少资源消耗，只是两个的侧重点不一样，有时间可以看看相关文章。

  const debounce = (callback: Function, wait: number) => {
    if (timer) {
      clearTimeout(timer)
    }
    timer = setTimeout(() => {
      callback()
    }, wait)
  }

  // 获取热搜
  const getHotwordFnc = async (localPath: string) => {
    // let localRes = await fetch(`/bllocal/${localPath}.json`).then((res: any) => {
    //   return res && res.json()
    // }).then((data: any) => {
    //   return data
    // }).catch((err: any) => {
    //   console.error(err)
    //   return {
    //     code: -1,
    //     note: '获取本地文件失败'
    //   }
    // })
    // if (localRes.code != -1) {
    //   setHotwordList(localRes.list)
    //   setSearchSuggest(localRes.list[0].keyword)
    // }
    // if (localRes.code == -1) {
      ApiRequest({ api: getHotword }).then((res: any) => {
        setHotwordList(res.list)
        setSearchSuggest(res.list[0].keyword)
      })
    // }

  }

  // 获取推荐关键词
  const getSearchSuggestFnc = (keyword: string) => {
    const params = {
      term: keyword,
    }
    ApiRequest({ api: getSearchSuggest, params }).then((res: any) => {
      setOptions(res.result.tag)
    })
  }

  const onOptionClick = (value: any) => {
    setSearchValue(value)
    setPopupVisible(false)
    onChange(value)
  }

  const onPopupVisibleChange = (e: boolean) => {
    //手动控制显示弹出层
    setPopupVisible(e)
  }

  //登录页关闭时
  const onDialogClose = () => {
    clearTimeout(qrTimer)
    clearInterval(qrVerificationTimer)
    setIsQrCodeExpired(false)
    setLoginDialogVisible(false)
  }

  //登录
  const toLogin = (context?: SubmitContext<Data>) => {
    // 账号密码登录
    if (context) {
      if (context.validateResult === true) {
        console.log(context)
      }
      // setIsLogin(true)
    } else {
      // setIsLogin(true)
      //TODO: 成功后。获取自己的信息、渲染头像、设置登录状态
      setLoginDialogVisible(false)
      getUserNavInfoFnc()
    }

  }

  const toRegister = () => {
    // TODO: 注册页面
    setIsRegister(true)
  }

  const onAvatarClick = () => {
    if (!loginInfo.face) {
      setLoginDialogVisible(true)
      getQrCodeFnc()
    } else {
      toUserCenter(loginInfo.mid)
    }
  }

  const toUserCenter = (mid: any) => {
    navigate('/aio/bilibili/user', {
      state: {
        mid
      }
    })
  }

  const parseCookies = (cookieString: string) => {
    let DedeUserID = cookieString.split("DedeUserID=")[1].split(";")[0]
    let bili_jct = cookieString.split("bili_jct=")[1].split(";")[0]
    let SESSDATA = cookieString.split("SESSDATA=")[1].split(";")[0]
    let _cookie: string = `DedeUserID=${DedeUserID};bili_jct=${bili_jct};SESSDATA=${SESSDATA};`
    return [_cookie, bili_jct];
  }


  const onLogout = () => {
    let _cookie = parseCookies(blCookie)
    let params = {
      cookie: _cookie[0],
      biliCSRF: _cookie[1]
    }
    console.log(parseCookies(blCookie))
    ApiRequest({ api: logout, params }).then((res: any) => {
      console.log('onLogout', res)
      if (res.code == 1) {
        MessagePlugin.success('退出登录成功')
        localStorage.setItem('loginInfo', '{}')
        setLoginInfo('{}')
      }
    })
  }

  const renderStat = (number: any, label: any): ReactNode => {
    return <div className={styles.statItem}>
      <div className={styles.statNum}>{number}</div>
      <div className={styles.statLabel}>{label}</div>
    </div>
  }

  const renderNavUserCard = (): ReactNode => {
    return <div
      className={styles.navUserCard}>
      <div className={`${styles.upName}`}>{loginInfo.uname}</div>
      <div className={styles.level}>
        <div>LV{loginInfo.level_info?.current_level}</div>
        <Progress theme='line' size='small' style={{ width: '200px' }}
          label={false} percentage={(loginInfo.level_info?.current_exp / loginInfo.level_info?.next_exp) * 100}
          color={{ direction: 'to right', from: '#ffd8d2', to: '#f6685d' }}
        />
        <div>LV{(loginInfo.level_info?.current_level) + 1}</div>
      </div>
      {/* <div className='bl-graySmallPrint'>`当前成长${loginInfo.level_info?.current_exp}，
        距升级率${(loginInfo.level_info?.current_level) + 1}
        还需要${loginInfo.level_info?.next_exp - loginInfo.level_info?.current_exp}`</div>` */}
      <div className={styles.stat}>
        {renderStat(loginInfo.following, '关注')}
        {renderStat(loginInfo.follower, '粉丝')}
        {renderStat(loginInfo.dynamic_count, '动态')}

      </div>
      <div className={styles.navUserCardBottom}>
        <Button onClick={()=>toUserCenter(loginInfo.mid)}>个人中心</Button>
        <Button onClick={onLogout}>退出登录</Button>
      </div>
    </div>
  }

  return <div className={`${styles.header} ${className}`}>
    <div className={styles.searchBlock}>
      <SelectInput
        className={styles.searchInput}
        value={searchValue}
        placeholder={searchSuggest ? searchSuggest : "请输入任意关键词"}
        popupVisible={popupVisible}
        onPopupVisibleChange={onPopupVisibleChange}
        allowInput
        clearable
        onInputChange={onInputChange}
        onEnter={() => onChange(searchValue)}
        suffixIcon={<SearchIcon />}
        panel={
          options.length ?
            <div className={styles.hotList}>
              <ul className={styles.searchBlockUl}>
                {options?.map((item: any, index: number) => (
                  <li key={index} onClick={() => onOptionClick(item.term)} className={styles.searchBlockLi}>
                    {item.term}
                  </li>
                ))}
              </ul>
            </div> :
            <div className={styles.hotList}>
              <div className={styles.hotTitle}>热搜</div>
              <Row gutter={16} className={styles.hotwordList}>
                {hotwordList?.map((item: any, index: any) => (
                  <Col span={6} key={index} >
                    <div className={styles.hotwordItem} key={index} onClick={() => onOptionClick(item.show_name)}>{`${index + 1}.${item.show_name}`}</div>
                  </Col>
                ))}
              </Row>
            </div>
        }
      />
      <Button shape="rectangle"
        size="medium"
        type="button"
        variant="base"
        onClick={() => onChange(searchValue ? searchValue : searchSuggest)}>搜索</Button>
    </div>

    {loginInfo.face ?
      <Popup
        // overlayInnerStyle={{ width: '300px', height: '200px' }}
        content={renderNavUserCard()}
        trigger="hover"
        placement="bottom"
        attach={(triggerNode) => triggerNode?.parentNode as any}
      >
        <Avatar
          className={styles.avatar}
          image={loginInfo.face}
          shape="circle"
          size="large"
          onClick={onAvatarClick}
        />
      </Popup>
      : <Avatar size="large" className={styles.avatar} onClick={onAvatarClick}>
        登录
      </Avatar>
    }
    <Dialog
      visible={loginDialogVisible}
      closeBtn
      closeOnEscKeydown
      closeOnOverlayClick
      confirmBtn={null}
      cancelBtn={null}
      mode="modal"
      placement="center"
      theme="default"
      onClose={onDialogClose}
    >
      {
        <div className={styles.dialogBlock}>
          <div className={styles.leftQR}>
            <div className={styles.qrCodeTitle}>扫描二维码登录</div>
            <div className={styles.qrCodeWrapper}>
              {QrCode.url && <img className={styles.qrCode} src={QrCode.url} alt="qrcode" />}
              {isQrCodeExpired && <div className={`${styles.qrCode} ${styles.qrCodeExpired}`} onClick={getQrCodeFnc}>二维码已过期请点击刷新</div>}
            </div>
          </div>
          <div className={styles.dialogInner}>
            <Radio.Group className={styles.dialogRadio} onChange={(value: any) => { setIsRegister(value) }} variant="default-filled" value={isRegister}>
              <Radio.Button value={false}>密码登录</Radio.Button>
              <Radio.Button value={true}>短信登录</Radio.Button>
            </Radio.Group>
            <Form form={formRef} statusIcon={true} onSubmit={toLogin} colon={true} labelWidth={0}>
              <FormItem name="account">
                <Input clearable={true} label={!isRegister ? '账号' : '+86'} placeholder={!isRegister ? '请输入账户名' : '请输入手机号'} />
              </FormItem>
              <FormItem name="password">
                <Input type="password" label={!isRegister ? '密码' : '验证码'} clearable={true} placeholder={!isRegister ? '请输入密码' : '请输入验证码'} />
              </FormItem>
              {!isRegister ? <FormItem>
                <Button theme="default" block onClick={toRegister}>
                  注册
                </Button>
                <Button theme="primary" type="submit" block>
                  登录
                </Button>
              </FormItem> :
                <FormItem>
                  <Button theme="primary" type="submit" block>
                    注册/登录
                  </Button>
                </FormItem>}
            </Form>
          </div>
        </div>

      }
    </Dialog>
  </div>
}

export default Header
